

#include "gpio.h"

/**-------------------------------------------------------
  * @函数名：CH32_Usart_Init(void)
  * @功能：     串口通信配置函数
  * @参数：     无
  * @返回值     无
***------------------------------------------------------*/
void CH32V_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

/*******************ADC输入引脚配置**********************！！！！！！！！！！！！！！！！！！！！*/
    GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_3|
                                   GPIO_Pin_4|
                                   GPIO_Pin_5|
                                   GPIO_Pin_7);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                //输入为ADC模式
    GPIO_Init(GPIOA, &GPIO_InitStructure);                       //打开A组使能
    GPIO_PinLockConfig(GPIOA,GPIO_Pin_3|
                             GPIO_Pin_4|
                             GPIO_Pin_5|
                             GPIO_Pin_7);


/*******************数字量输入引脚配置*********************!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1**/
    GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_12|
                                   GPIO_Pin_13|
                                   GPIO_Pin_14|
                                   GPIO_Pin_1|
                                   GPIO_Pin_2|
                                   GPIO_Pin_3|
                                   GPIO_Pin_4|
                                   GPIO_Pin_5|
                                   GPIO_Pin_6|
                                   GPIO_Pin_7);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;               //设置为输入上拉
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;           //最大输出速度50Mhz
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_PinLockConfig(GPIOB,GPIO_Pin_12|
                             GPIO_Pin_13|
                             GPIO_Pin_14|
                             GPIO_Pin_15);                       //锁定配置

/*******************数字量输出引脚配置**********************!!!!!!!!!!!!!!!!!!!!!!!!!*/
    GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_13|
                                   GPIO_Pin_14);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_PinLockConfig(GPIOC,GPIO_Pin_13|
                             GPIO_Pin_14);


    GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_3|
                                   GPIO_Pin_4);

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_PinLockConfig(GPIOD,GPIO_Pin_3|
                             GPIO_Pin_4);

/*******************UART6串口引脚配置***********************/
    // 初始化USRT6_EN引脚配置为Out_PP模式
    GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_2);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_PinLockConfig(GPIOC,GPIO_Pin_2);

    // 初始化USRT6_TX引脚配置为AF_PP模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_PinLockConfig(GPIOC, GPIO_Pin_0);

    // 初始化USRT6_RX引脚配置为FLOATING模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_PinLockConfig(GPIOC, GPIO_Pin_1);

/*******************I2C_SCL引脚配置***********************/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_12;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_PinLockConfig(GPIOB,GPIO_Pin_10);
}

/**-------------------------------------------------------
  * @函数名：SDA_OUT(void)
  * @功能：     I2C设置为数据输出
  * @参数：     无
  * @返回值     无
***------------------------------------------------------*/
void SDA_OUT(void)
{
   GPIO_InitTypeDef  GPIO_InitStructure;
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_Init(GPIOB, &GPIO_InitStructure);
 //  GPIO_PinLockConfig(GPIOB,GPIO_Pin_11);
}

/**-------------------------------------------------------
  * @函数名：SDA_IN(void)
  * @功能：     I2C设置为数据接收
  * @参数：     无
  * @返回值     无
***------------------------------------------------------*/
void SDA_IN(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
 //   GPIO_PinLockConfig(GPIOB,GPIO_Pin_11);
}

/**-------------------------------------------------------
  * @函数名：  EXTI2_INT_INIT(void)
  * @功能：     外部中断配置,电池推出按键
  * @参数：     无
  * @返回值     无
***------------------------------------------------------*/
void EXTI2_INT_INIT(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
    EXTI_InitStructure.EXTI_Line=EXTI_Line2;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;              //上升沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
}

/**-------------------------------------------------------
  * @函数名：EXTI3_INT_INIT(void)
  * @功能：     外部中断配置，电池种类设置
  * @参数：     无
  * @返回值     无
***------------------------------------------------------*/
void EXTI3_INT_INIT(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
    EXTI_InitStructure.EXTI_Line=EXTI_Line3;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;              //下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
}

/**-------------------------------------------------------
  * @函数名：EXTI4_INT_INIT(void)
  * @功能：     外部中断配置，电池活化设置
  * @参数：     无
  * @返回值  无
***------------------------------------------------------*/
void EXTI4_INT_INIT(void)
{
    EXTI_InitTypeDef EXTI_InitStructure;

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
    EXTI_InitStructure.EXTI_Line=EXTI_Line4;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;              //下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
}











//******************************************************************************
//@ 版         权 ：无锡市欧瑞杰电子科技有限公司
//@ 工         程 ：FTU电池充电式开关电源
//@ 版         本 ：Version 1.1
//@ 密          级：
//@ 历史记录：
//@ 作          者：唐建 (18224454640)

#include "sys_con.h"

vu8 BT_Connect_STA;         //电池连接状态
vu8 BT_OFFLINE_Flage;       //电池离线标志位
vu16 offline_Temp;          //电池离线判断次数
vu8  offline_test_delay;    //离线延时（关闭充电后等待电池掉电）

/**-------------------------------------------------------
  * @函数名：SysInit_CH32V(void)
  * @功能：     初始化配置函数
  * @参数：     无
  * @返回值  无
***------------------------------------------------------*/
void SysInit_CH32V(void)
{
//    SystemInit();          //时钟配置
    SystemCoreClockUpdate(); //时钟配置
    CH32_RCC_Init();         //时钟配置
    Delay_Init();            //延时函数初始化（要使用必须进行初始化）

    CH32V_GPIO_Init();       //GPIO初始化配置



//    CH32V_UART6_Init();      //串口通信配置
//
//    CH32V_TIM2_Init();     //定时器2初始化配置
//    CH32V_TIM3_Init();     //定时器3初始化配置
//    CH32V_TIM4_Init();     //定时器4初始化配置
//
//    EXTI2_INT_INIT();      //电池投入与退出按键
////    EXTI3_INT_INIT();      //电池种类选择按键
//    EXTI4_INT_INIT();      //电池种类切换按键
//
//    CH32V_ADC_Init();        //ADC采样配置
//    CH32V_NVIC_Init();     //中断向量配置
 //   CH32V_IWDGInit(40000); //看门狗配置
}

/**-------------------------------------------------------
  * @函数名：CH32_RCC_Init(void)
  * @功能：     CH32V时钟配置
  * @参数：     无
  * @返回值  无
***------------------------------------------------------*/
void CH32_RCC_Init(void)
{
    /* GPIOB clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD , ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE , ENABLE);


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 , ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART6 , ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div8);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);     //Remind
}

/**-------------------------------------------------------
  * @函数名：CH32V_NVIC_Init(void)
  * @功能：     CH32V中断向量初始化
  * @参数：     无
  * @返回值  无
***------------------------------------------------------*/
void CH32V_NVIC_Init(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);       //

    //-----------------time2中断优先级配置-------------
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    //-----------------UART6中断优先级配置-------------
    NVIC_InitStructure.NVIC_IRQChannel = UART6_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    //-----------------按键中断优先级配置-------------
    NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;            //外部中断线4中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    //-----------------按键中断优先级配置-------------
    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;           //外部中断线9-5中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    //-----------------time3中断优先级配置-------------
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    //-----------------time4中断优先级配置-------------
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

/**-------------------------------------------------------
  * @函数名：SysPARInit(void)
  * @功能：     系统运行初始化
  * @参数：     无
  * @返回值  无
***------------------------------------------------------*/
void SysPARInit(void)
{
    B_SETLED_La;                            //上电初始化电池设置为铅酸，保证电源不重启，下一步再从EEPROM读取
    Rxdata_flag=0;                          //不发送任何数据
    Ctrl_RX_flag=5;                         //停止活化状态
    Ctrl_flag_STA=5;                        //当前为停止活化状态
    ACT_STOP_UV_flag=0;                     //活化截止标志位置零
    BT_UVBH_flag = 0;                       //过放标志位清零
    ACT_NUM=0;                              //活化次数置0

    Init_CZCD_time = 0;                     //初始化强制打开充电器时间
    offline_DEC = 0;                        //初始化强制打开时间到标志位
    BT_OFFLINE_Flage=0;                     //初始未离线
    BT_Connect_STA = BT_Connect_OK;         //电池链接OK
    offline_Temp = 0;
    frist_offline_DEC = 1;
    frist_offline_Count=0;
//  BT_CAP=7;                               //默认电池容量7AH
//  ACT_STOP_UV=0x05D1;                     //默认放电截止电压23V
//  SOC_FULT = 50;                          //默认预估电池剩余容量是额定容量的50%以下时报警

///上电初始化数字输出引脚
    DISABLE_B_CD;                           //上电初始状态先关闭充电器
    B_VL_Not_Happen;                        //清0电池欠压故障引脚电平
    B_GZ_Not_Happen;                        //清0电池故障引脚电平
    BT_STAE_INF = 0x0000;                   //清除故障状态位
    CLOSE_D1_CD;                            //关闭充电指示灯
    CLOSE_D3_HH;                            //关闭活化指示灯
    CLOSE_D2_FD;                            //关闭放电指示灯
    DISABLE_HK;                             //关闭活化动作,禁止电源输出钳位
    DISABLE_B_RON;                          //禁止内阻检测，引脚上电默认为低
    B_ON;                                   //强制打开电池供电脚
    mun_main = 0;

    RON_TIM_step = 0;

    offline_test_delay = 0;                 //离线延时（关闭充电后等待电池掉电）
    CHI_BT_count = 0;
}

/**-------------------------------------------------------
  * @函数名：Init_BT_Connect(void)
  * @功能：    初次连接电池时判断电池是否连接正确和过压
  * @参数：     无
  * @返回值  无
***------------------------------------------------------*/
void Init_BT_Connect(void)
{
    if((VBT<BT_ROV)&&(BT_FJ==1))
      {
        ENABLE_B_CD;             //打开电池充电继电器
        BT_Connect_STA = BT_Connect_OK;
      }
    else
      {
        B_OFF;                   //初始化关闭放电动作
        DISABLE_B_CD;            //关闭电池充电继电器
        BT_Connect_STA = BT_Connect_ERROR;
      }
}
/**-------------------------------------------------------
  * @函数名：Init_BT_OffineDetect(void)
  * @功能：    初次上电时电池离线检测
  * @参数：     无
  * @返回值  无
***------------------------------------------------------*/
void Init_BT_OffineDetect(void)
{
/*
    DISABLE_B_CD;
    B_ON;
    if(VBT<=BT_LX){BT_STAE_INF=BT_STAE_INF|0x0010;BT_OFFLINE_Flage=1;}    //电池离线
    if(VBT>BT_RLX){BT_STAE_INF=BT_STAE_INF&0xFFEF;BT_OFFLINE_Flage=0;}    //电池在线
*/
    if((offline_DEC ==1)&&(VBT<BT_ROV)&&(BT_FJ==1))                       //定时时间到,，电池未过压，电池未反接
      {
        if (PW_DOWN==0)                                                                      //高压输入在线
        {
                    DISABLE_B_CD;
                    B_ON;
//                    offline_Temp++;
                    offline_test_delay = 1;
                    if(offline_Temp<=4)
                      {
                        if(VBT>BT_RLX){BT_STAE_INF=BT_STAE_INF&0xFFEF;BT_OFFLINE_Flage=0;}    //电池肯定在线
                        if(VBT<=BT_LX)                                                        //电池可能离线
                          {
                            BT_STAE_INF=BT_STAE_INF|0x0010;
                            BT_OFFLINE_Flage=1;
            /*
                            ENABLE_B_CD;
                            Delay_Ms(200000);
                            if(CHI_BT>0x019A){BT_STAE_INF=BT_STAE_INF&0xFFEF;BT_OFFLINE_Flage=0;}
                            if((CHI_BT<0x019A)&&(VBT>BT_UV)){BT_STAE_INF=BT_STAE_INF|0x0010;BT_OFFLINE_Flage=1;}
            */
                          }
                      }
                      else
                      {
                       ENABLE_B_CD;
                       offline_Temp = 0;
                       offline_DEC = 0;

                       offline_test_delay = 0;
                      }
        }

        else
          {
            ENABLE_B_CD;
            offline_Temp = 0;
            offline_DEC = 0;
            BT_STAE_INF=BT_STAE_INF&0xFFEF;
            BT_OFFLINE_Flage=0;

            offline_test_delay = 0;
          }
      }
    else
    {
        Init_BT_Connect();
    }
}
/**-------------------------------------------------------
  * @函数名：BT_MODE_SEC(void)
  * @功能：    初次上电时电池型号检测
  * @参数：     无
  * @返回值  无
***------------------------------------------------------*/
void Init_BT_MODE_SEC(void)
{
    if(BT_MODE==BT_Li)                                      //当前状态为锂电池
      {
        BT_MODE=BT_Li;                                      //将电池状态切换为铅酸电池                      -》锂电池？？？
        BT_UV  =BT_UV_Li;                                   //电池欠压状态切换为铅酸电池
        BT_RUV =BT_RUV_Li;                                  //电池欠压状态切换为铅酸电池
        OverDischarge_V=OverDischarge_V_Li;                 //电池过放关断点设置为铅酸电池
        B_SETLED_Li;                                        //LED灯指示为铅酸电池
      }
    else
      {
        BT_MODE=BT_La;                                      //将电池状态切换为铅酸电池
        BT_UV  =BT_UV_La;                                   //电池欠压状态切换为铅酸电池
        BT_RUV =BT_RUV_La;                                  //电池欠压状态切换为铅酸电池
        OverDischarge_V=OverDischarge_V_La;                 //电池过放关断点设置为铅酸电池
        B_SETLED_La;
      }
}
/**-------------------------------------------------------
  * @函数名：CH32V_IWDGInit(void)
  * @功能：     CH32V独立看门狗初始化函数
  * @参数：     多少MS溢出一次
  * @返回值  无
***------------------------------------------------------*/
void CH32V_IWDGInit(uint32_t TimeoutFreMs)                 /* 2 -  3276*/
{
    uint32_t ReloadValue;
    IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);         // Enable write access to IWDG_PR
    IWDG_SetPrescaler(IWDG_Prescaler_32);                 // IWDG counter clock: 40KHz(LSI) / 32 = 1.25 KHz

    if(TimeoutFreMs < 2)
    {
        TimeoutFreMs = 2;
    }

    if(TimeoutFreMs > 3276)
    {
        TimeoutFreMs = 3276;
    }

    ReloadValue = ((TimeoutFreMs * 1250)/1000) - 1;        // Set counter reload value to 349 *//* range from 0 to 4095
    IWDG_SetReload(ReloadValue);
    IWDG_ReloadCounter();                                  //Reload IWDG counter
    IWDG_Enable();
}
